import requests
import json
import base64
from flask import Flask, request, jsonify, render_template

app = Flask(__name__)

# 全局对话历史
conversation_history = []

# 全局 Access Tokens
chat_access_token = None
image_access_token = None

# 替换为您的 API Key 和 Secret Key（全局变量）
CHAT_API_KEY = 'qHzm2g9f2y5s7k10lXEbenZs'
CHAT_SECRET_KEY = '0NKrjr15isRenqbnHcAd0QFT3747hrS5'
IMAGE_API_KEY = 'ID7NOXVpMPJHEaNu6EzhmhG6'
IMAGE_SECRET_KEY = 'CsyAwHhyclbOsCu2095KKPOYadwSbXwb'

def get_access_token(api_key, secret_key, token_type='chat'):
    global chat_access_token, image_access_token

    if token_type == 'chat' and chat_access_token is not None:
        return chat_access_token  # 如果已有 chat access_token，直接返回
    elif token_type == 'image' and image_access_token is not None:
        return image_access_token  # 如果已有 image access_token，直接返回

    url = f"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={api_key}&client_secret={secret_key}"
    response = requests.post(url)
    if response.status_code == 200:
        access_token = response.json().get('access_token')
        if access_token:
            if token_type == 'chat':
                chat_access_token = access_token
            elif token_type == 'image':
                image_access_token = access_token
            return access_token
        else:
            raise Exception("获取 Access Token 失败: 没有返回 access_token")
    else:
        raise Exception(f"获取 Access Token 失败，状态码: {response.status_code}, 响应: {response.text}")

def ernie_4_0_8k_chat(access_token, messages):
    url = f"https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token={access_token}"
    headers = {'Content-Type': 'application/json'}
    payload = {
        "messages": messages,
        "model": "ERNIE-4.0-8K"
    }
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f"调用 ERNIE-4.0-8K API 失败，状态码: {response.status_code}, 响应: {response.text}")

def recognize_general_objects(access_token, image_base64):
    url = f"https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general?access_token={access_token}"
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    data = {
        'image': image_base64,
        'baike_num': 1  # 返回百科信息的个数
    }
    response = requests.post(url, headers=headers, data=data)
    print("API 响应状态码:", response.status_code)
    print("API 响应内容:", response.json())  # 打印完整响应内容以供调试
    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f"调用通用物体和场景识别 API 失败，状态码: {response.status_code}, 响应: {response.text}")

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/chat', methods=['POST'])
def chat():
    global conversation_history
    data = request.json
    user_message = data.get('message', '').strip()
    if not user_message:
        return jsonify({"error": "未提供消息"}), 400

    # 添加用户输入到对话历史中
    conversation_history.append({"role": "user", "content": user_message})
    print("对话历史更新（用户消息）:", conversation_history)  # 调试输出

    try:
        access_token = get_access_token(CHAT_API_KEY, CHAT_SECRET_KEY, token_type='chat')
        response = ernie_4_0_8k_chat(access_token, conversation_history)
        print("API 响应内容:", response)  # 调试信息

        # 检查是否有返回结果
        ai_response = response.get('result')
        if not ai_response:
            ai_response = "未获取到回复"
        conversation_history.append({"role": "assistant", "content": ai_response})
        print("对话历史更新（AI回复）:", conversation_history)  # 调试输出

        return jsonify({"result": ai_response})

    except Exception as e:
        error_message = f"聊天请求出错: {str(e)}"
        conversation_history.append({"role": "assistant", "content": error_message})
        return jsonify({"error": error_message}), 500

@app.route('/upload-image', methods=['POST'])
def upload_image():
    global conversation_history
    if 'image' not in request.files:
        return jsonify({"error": "未上传图像"}), 400
    file = request.files['image']
    image_base64 = base64.b64encode(file.read()).decode('utf-8')

    try:
        # 获取 access_token
        access_token = get_access_token(IMAGE_API_KEY, IMAGE_SECRET_KEY, token_type='image')

        # 调用通用物体和场景识别接口
        result = recognize_general_objects(access_token, image_base64)

        if result.get('result'):
            results = result['result']
            result_text = []
            for item in results:
                description = f"关键词: {item['keyword']}, 置信度: {item['score'] * 100:.2f}%"
                if 'baike_info' in item and item['baike_info']:
                    baike_desc = item['baike_info'].get('description', '')
                    if len(baike_desc) > 100:
                        baike_desc = baike_desc[:100] + "..."
                    description += f", 百科描述: {baike_desc}"
                result_text.append(description)

            ai_response = '\n'.join(result_text)
            conversation_history.append({"role": "user", "content": f"图像识别结果: \n{ai_response}"+"请解释图像识别的结果",})
            print("图像识别结果添加到历史:", conversation_history)  # 调试输出

    

            # 调用AI解释图像识别结果
            chat_access_token = get_access_token(CHAT_API_KEY, CHAT_SECRET_KEY, token_type='chat')
            response = ernie_4_0_8k_chat(chat_access_token, conversation_history)
            print("AI解释响应:", response)  # 调试信息
            explanation_response = response.get('result', "未获取到解释")

            conversation_history.append({"role": "assistant", "content": explanation_response})
            print("对话历史更新（AI解释）:", conversation_history)  # 调试输出

            return jsonify({"result": explanation_response})

        else:
            ai_response = "未识别出任何物体或场景"
            conversation_history.append({"role": "user", "content": ai_response})
            return jsonify({"result": ai_response})

    except Exception as e:
        error_message = f"图像处理出错: {str(e)}"
        conversation_history.append({"role": "assistant", "content": error_message})
        return jsonify({"error": error_message}), 500

if __name__ == "__main__":
    app.run(debug=True)
